/*
   Copyright (c) 2019 Shanghai Xuanzi Technology Co. Ltd https://xuanzi.ltd
   XZMindMap is licensed under the Mulan PSL v1.
   You can use this software according to the terms and conditions of the Mulan PSL v1.
   You may obtain a copy of Mulan PSL v1 at:
      http://license.coscl.org.cn/MulanPSL
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
   PURPOSE.
   See the Mulan PSL v1 for more details.

*/

package xuanzi.openmind.nodes;

import java.util.ArrayList;
import java.util.List;

import xuanzi.commons.graphics.Canvas;
import xuanzi.commons.graphics.Paint;
import xuanzi.commons.graphics.PointF;
import xuanzi.commons.graphics.BoxF;
import xuanzi.openmind.lines.Line;
import xuanzi.openmind.renders.RenderBuffer;
import xuanzi.openmind.scenes.base.Scene;
import xuanzi.openmind.shapes.Shape;

public class Node {
	
	long timestamp;

	Scene scene;
	
	public RenderBuffer renderBuffer ;
 
	String topic,label,memo;
	
	Line line ;
	
	int level;
	
	int childTotal;
	
	Shape shape;
	
	int index;
	
	Node parent;
	
	JSON data ;
	
	String id;
	
	boolean open = true;
	
	float centerX,centerY;
	
	Style style;
	
	public void setOpen(boolean open) {
		this.open = open;
	}
	
	public boolean isOpen() {
		return open;
	}
	
	public void fromJSON(JSON json) {
		items.clear();
		data = json;
		if(json.has("children")) {
			JSON[] itemsx = json.array("children");
			for(int i=0;i<itemsx.length;i++) {
				JSON item = itemsx[i];
				Node node = new Node();
				node.fromJSON(item);
				items.add(node);
				node.parent = this;
			}
		}
		
		if(data.has("topic")) {
			topic = data.value("topic");
		}
		if(data.has("label")) {
			label = json.value("label");
		}
		if(data.has("memo")) {
			memo = json.value("memo");
		}
	}
	
	List<Media> medias ;
	
	public JSON toJSON() {
		if(data==null) {
			data = JSON.create();
			if(items!=null) {
				for(Node node:items) {
					JSON it = node.toJSON();
					data.push("children", it);
				}
			}
		}else {
			if(items!=null) {
				for(Node node:items) {
					node.toJSON(); 
				}
			}
		}
		if(topic!=null)
			data.value("topic",topic);
		if(label!=null)
			data.value("label",label);
		if(memo!=null)
			data.value("memo", memo);
		return data;
	}
	
	
	public float getCenterX() {
		return centerX;
	}
	
	public float getCenterY() {
		return centerY;
	}
	
	public void setCenterX(float centerX) {
		this.centerX = centerX;
	}
	
	public void setCenterY(float centerY) {
		this.centerY = centerY;
	}
	
	public void addMedia(Media media) {
		if(medias==null)
			medias = new ArrayList<>();
		medias.add(media);
		media.setNode(this);
	}
	
	public void removeMedia(Media media) {
		if(medias==null)
			return ;
		media.setNode(null);
		medias.remove(media);
	}
	
	public long getTimestamp() {
		return timestamp;
	}
	
	public void setTimestamp(long timestamp) {
		this.timestamp = timestamp;
	}
	
	public int getChildTotal() {
		return childTotal;
	}
	
	public void setChildTotal(int childTotal) {
		this.childTotal = childTotal;
	}
	
	public void setIndex(int index) {
		this.index = index;
	}
	
	public int getIndex() {
		return index;
	}
	
	public void setParent(Node parent) {
		this.parent = parent;
	}
	
	public Node getParent() {
		return parent;
	}
	
	public void setShape(Shape shape) {
		this.shape = shape;
	}
	
	public Shape getShape() {
		return shape;
	}
	
	public void setLevel(int level) {
		this.level = level;
	}
	
	public int getLevel() {
		return level;
	}
	
	public List<Media> getMedias() {
		return medias;
	}
	
	private List<Node> items = new ArrayList<Node>();

 
	 
	 
	public Node testPoint(PointF point) {
		if(renderBuffer!=null&&renderBuffer.bound.contains(point.x,point.y)) {
			return this;
		}else if(renderBuffer.handlerBox.contains(point.x, point.y)) {
			return this;
		}else if(items!=null){
			for(Node item : items) {
				Node node = item.testPoint(point);
				if(node!=null)
					return node;
			}
		}
		return null;
	}
	
	public Media testMediaPoint(PointF point) {
		if(medias!=null) {
			for(Media media:medias) {
				if(media.contains(point.x,point.y)) {
					return media;
				}
			}
		}
		
		if(renderBuffer.labelBox!=null&&renderBuffer.labelBox.contains(point.x,point.y))
			return renderBuffer.labelBox;
		if(renderBuffer.memoBox!=null&&renderBuffer.memoBox.contains(point.x, point.y))
			return renderBuffer.memoBox;
		if(renderBuffer.textBox.contains(point.x, point.y))
			return renderBuffer.textBox;
		return null;
	}
	
	public Node() { 
	//	box.add(upBox);
		
	//	box.add(bottomBox);
	}
	
	public Node(String string) {
		this();
		setTopic(string); 
	}

 
	
	public void setScene(Scene scene) {
		this.scene = scene;
		
	}
	
	public Scene getScene() {
		return scene;
	}
	
	public void setLine(Line line) {
		this.line = line;
	}
	
	public Line getLine() {
		return line;
	}
	
	 
	public Node getNode(int at) {
		return items.get(at);
	}
	
	public int getNodeCount() {
		return items.size();
	}
	
	public Node addNode(String topic) {
		Node item = new Node(topic); 
		addNode(item);
		
		return item;
	}
	
	public void remove(Node node) {
		
	}
	
	public Style applyStyle() {
		if(style==null)
			style = new Style();
		return style;
	}
	
	public Style getStyle() {
		return style;
	}

	public void addNode(Node item) {
		if(items==null)
			items = new ArrayList<>();
		items.add(item);
		if(data!=null)
			data.push("children", item.data);
		item.setParent(this);
	}
	
 
	
	
	public String getTopic() { 
			return topic;
	}
	
	public void setTopic(String topic) { 
		if(renderBuffer!=null) {
			renderBuffer.topic = topic;
			renderBuffer.reszie();
		}
			this.topic = topic;
	}
	
	public void setLabel(String label) { 
		if(renderBuffer!=null) {
			renderBuffer.topic = topic;
			renderBuffer.reszie();
		}
		this.label = label;
	}
	
	public String getLabel() {
		return label;
	} 
	 
	public void setMemo(String memo) {
		this.memo = memo;
	}
	
	public String getMemo() {
		return memo;
	}
  
	Paint paint = new Paint();
	
	public void draw(Canvas canvas) {
		
		/*
		if(selected)
			paint.borderColor = 0xFFFF00ff;
		else
			paint.borderColor = 0xff000000; 
		centerBox.draw(canvas, paint);
		
		if(items!=null) {
		
			for(Node item : items ) {
				 renderBuffer.line.draw(canvas, this,item);
				//canvas.drawLine(getBox().centerX(), getBox().centerY(), item.getBox().centerX(), item.getBox().centerY(), paint);
				item.draw(canvas);
			}
		}
		renderBuffer.shape.draw(canvas, this,paint); 
		*/
		scene.getRender().draw(canvas, this);
		
	}
	
	public boolean isSelected() {
		return selected;
	}
	
	
	public void requestLayout() {
		scene.setupNode(this);
	}
	
	boolean selected;

	public void setSelected(boolean b) {
		// TODO Auto-generated method stub
		selected = b;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public BoxF getNodeBound() {
		// TODO Auto-generated method stub
		return renderBuffer.shapeBound;
	}


	public boolean isEmpty() { 
		return getNodeCount()==0;
	}
 
	
	
}
